<template>
  <t-form ref="refForm" v-bind="$attrs" v-on="$listeners">
    <template v-if="Array.isArray(schema)">
      <tiny-form-item
        ref="refFormItem"
        v-for="(item, index) in schema"
        :key="index"
        v-bind="item"
        :model="$attrs.model"
      />
    </template>
    <template v-else-if="isFunction(schema)">
      <tiny-form-item
        ref="refFormItem"
        v-for="(item, index) in schema()"
        :key="index"
        v-bind="item"
        :model="$attrs.model"
      />
    </template>
  </t-form>
</template>

<script>
import TinyFormItem from './TinyFormItem.vue';
// TODO 初始化数据
export default {
  name: 'TinyForm',
  components: {
    TinyFormItem,
  },
  props: {
    /**
     * @description 表单数据
     * @type {Array|Function}
     * @required true
     */
    schema: {
      type: [Array, Function],
      default: () => [],
    },
  },
  data() {
    return {
      model: {},
    };
  },
  methods: {
    /**
     * @description 判断是否是函数
     * @param {Function} fn
     * @returns {Boolean}
     */
    isFunction(fn) {
      return Object.prototype.toString.call(fn) === '[object Function]';
    },
    validate() {
      return new Promise(async (resolve, reject) => {
        const result = await this.$refs.refForm.validate();

        if (Object.prototype.toString.call(result) === '[object Boolean]' && result) {
          resolve();
        }
      });
    },
    reset() {
      if (!Array.isArray(this.$refs.refFormItem)) {
        return;
      }

      for (const item of this.$refs.refFormItem) {
        item.reset();
      }
    },
    clearValidate() {
      this.$refs.refForm.clearValidate();
    },
    getFormData() {
      // 获取表单数据
      return this.model;
    },
    setFormData(obj = {}) {
      // 设置表单数据
      try {
        if (Object.prototype.toString.call(obj) !== '[object Object]') {
          throw new Error('please set object !');
        }

        this.model = {
          ...this.model,
          ...obj,
        };
      } catch (e) {
        console.error(e.message || 'error');
      }
    },
  },
};
</script>
